﻿using System;

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;

namespace BlamanticUI.Components;

/// <summary>
/// Render a anchor HTML tag of  <see cref="Item"/> component.
/// </summary>
[HtmlTag("a")]
public class LinkItem : Item,IHasLink,IDisposable
{
    private string? _hrefAbsolute;
    /// <summary>
    /// Initializes an instance of a new <see cref="LinkItem"/> class.
    /// </summary>
    public LinkItem()
    {
    }

    [Inject]NavigationManager NavigationManager { get; set; }
    /// <summary>
    /// Gets or sets a value representing the URL matching behavior.
    /// </summary>
    [Parameter] public NavLinkMatch Match { get; set; } = NavLinkMatch.All;
    /// <summary>
    /// A string of url address that will navigate to.
    /// </summary>
    [Parameter][HtmlAttribute("href")]public string Link { get; set; }

    protected override void OnInitialized()
    {
        NavigationManager.LocationChanged += new EventHandler<LocationChangedEventArgs>(OnLocationChanged);
    }

    private void OnLocationChanged(object? sender, LocationChangedEventArgs args)
    {
        bool flag = ShouldMatch(args.Location);
        if (flag != Active)
        {
            Active = flag;
            StateHasChanged();
        }
    }
    private bool ShouldMatch(string currentUriAbsolute)
    {
        if (_hrefAbsolute == null)
        {
            return false;
        }

        if (EqualsHrefExactlyOrIfTrailingSlashAdded(currentUriAbsolute))
        {
            return true;
        }

        if (Match == NavLinkMatch.Prefix && IsStrictlyPrefixWithSeparator(currentUriAbsolute, _hrefAbsolute))
        {
            return true;
        }

        return false;
    }
    private bool EqualsHrefExactlyOrIfTrailingSlashAdded(string currentUriAbsolute)
    {
        if (string.Equals(currentUriAbsolute, _hrefAbsolute, StringComparison.OrdinalIgnoreCase))
        {
            return true;
        }

        if (currentUriAbsolute.Length == _hrefAbsolute!.Length - 1 && _hrefAbsolute![_hrefAbsolute!.Length - 1] == '/' && _hrefAbsolute!.StartsWith(currentUriAbsolute, StringComparison.OrdinalIgnoreCase))
        {
            return true;
        }

        return false;
    }
    private static bool IsStrictlyPrefixWithSeparator(string value, string prefix)
    {
        int length = prefix.Length;
        if (value.Length > length)
        {
            if (value.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
            {
                if (length != 0 && char.IsLetterOrDigit(prefix[length - 1]))
                {
                    return !char.IsLetterOrDigit(value[length]);
                }

                return true;
            }

            return false;
        }

        return false;
    }
    
    public void Dispose()
    {
        NavigationManager.LocationChanged -= new EventHandler<LocationChangedEventArgs>(OnLocationChanged);
    }
}
